import React from 'react';
import { Common } from 'UtilsCommon';
import { Link } from 'Configs';
import { usePageAxis } from 'UseHooks';
import PropertyItem from './propertyItem';
import * as styles from '../styles/view.scss';

const load = (property, view, pageAxis) => {
  if (property.loadActionName) pageAxis.invokeEventAction(property.loadActionName, { property, view, pageAxis });
  else if (property.loadAction) pageAxis.invokeEventAction2(property.loadAction, { property, view, pageAxis });
};

const invokeEventAction = (property, view, pageAxis, e) => {
  if (property.eventActionName) pageAxis.invokeEventAction(property.eventActionName, { property, view, pageAxis, e });
  else if (property.eventAction) pageAxis.invokeEventAction2(property.eventAction, { property, view, pageAxis, e });
};

const getPropertyItem = (p, property, pageId) => {
  if (!p.id) p.id = Common.createGuid();
  if (p.isNullable === undefined) p.isNullable = true;
  const props = { property: p, view: property, pageId, key: p.key || p.id };
  return <PropertyItem {...props} />;
};

const renderProperties = (property, pageId) => {
  property.properties = property.properties || [];
  return property.properties.map(m => getPropertyItem(m, property, pageId));
};

const renderProperties2 = (properties, view, pageId) => {
  return properties.map(m => getPropertyItem(m, view, pageId));
};

const getProps = (props) => {
  const { property, view, pageId } = props;
  if (!property.id) property.id = Common.createGuid();
  const pageAxis = usePageAxis.getPageAxis(pageId);
  return { property, view, pageId, pageAxis };
};

const getClassName = (property, styles, defaultClassName) => {
  let className = property.className || defaultClassName;
  if (className && styles[className]) className = styles[className];
  return className;
};

const getClassNames = (property, disabled) => {
  const { className, cssTemplate, isButton } = property;

  const cNames = [];

  if (className) cNames.push(className);
  if (cssTemplate) cNames.push(cssTemplate.cssName);
  if (isButton && !disabled) cNames.push('buttonActive');

  return cNames.join(' ');
};

const getLinkAction = (p, record) => {
  const text = p.text;
  if (!Common.isNullOrEmpty(text)) {
    let url = p.pageUrl; let v;

    p.propertyNames.forEach(n => {
      v = record[n];
      url = url.replace("#{" + n + "}", encodeURIComponent(v));
    });

    url = Common.addUrlRandom(url);

    return <Link to={url} key={p.name}>{text}</Link>;
  }
  return text;
};

const getImageLink = (d, i) => {
  const src = Common.getImageUrl(d.imageUrl);
  return (
    <Link key={i} to={d.url}>
      <img alt='' src={src} />
      <span>{d.text}</span>
    </Link>
  );
};

const getRightImageLink = (d, i) => {
  const src = Common.getImageUrl(d.imageUrl);
  return (
    <Link key={i} to={d.url}>
      <span>{d.text}</span>
      <img alt='' src={src} />
    </Link>
  );
};

const initSetView = (property) => {
  const rowDict = {};
  let xList = [];

  property.properties.forEach(p => {
    p.id = p.id || Common.createGuid();
    p.rowId = p.rowId || Common.createGuid();
    if (rowDict[p.x] === undefined) { rowDict[p.x] = []; xList.push({ rowId: p.rowId, x: p.x, property: p }); }
    rowDict[p.x].push(p);
  });

  xList = xList.sort((a, b) => a.x > b.x ? 1 : -1);

  for (const key in rowDict) rowDict[key] = rowDict[key].sort((a, b) => a.y > b.y ? 1 : -1);

  property.rowsCols = { xList, rowDictionary: rowDict };
};

const rendRowCols = (row, colList, property, pageId) => {
  return (<div key={row.rowId} style={row.property.rowStyle} className={styles[row.property.rowClassName || 'divRow']}>
    {colList.map(c => getPropertyItem(c, property, pageId))}</div>);
};

const renderView = (property, pageId) => {
  const { xList, rowDictionary } = property.rowsCols;
  return (
    <React.Fragment>
      {xList.map(m => rendRowCols(m, rowDictionary[m.x], property, pageId))}
    </React.Fragment>
  );
};

const getEntity = (property) => {
  if (property.entity) return property.entity;

  if (property.entityPrimaryKey && property.entityName) {
    property.entity = { name: property.entityName, primaryKey: property.entityPrimaryKey };
    return property.entity;
  }
  else if (property.entityForm) {
    const { name, primaryKey } = property.entityForm;

    property.entity = { name, primaryKey };
    return property.entity;
  }
};

const setStyle = (style) => {
  if (!style) return style;
  style = { ...style };
  if (style.backgroundImage && style.backgroundImage.indexOf('url(') < 0) {
    style.backgroundImage = `url(${style.backgroundImage})`;
  }
  return style;
};

const setValueTextName = (property) => {
  if (property.valueName || property.textName) return;

  const { serviceDataSource } = property;
  let valueName = 'value';
  let textName = 'text';

  if (serviceDataSource && serviceDataSource.valueName) valueName = serviceDataSource.valueName;
  if (serviceDataSource && serviceDataSource.textName) textName = serviceDataSource.textName;

  property.valueName = valueName;
  property.textName = textName;
};

const getInitValue = (property, initName) => {
  let value = null;
  if (!Common.isNullOrEmpty(property.value)) value = property.value;
  else if (!Common.isNullOrEmpty(property.defaultValue)) value = property.defaultValue;
  else if (property.isCurrentDay) value = Common.getCurrentDate().substr(0, 10);
  else if (initName && !Common.isNullOrEmpty(property[initName])) value = property[initName];

  const { isBind, data, name, propertyName } = property;
  const name2 = propertyName || name;
  if (value && isBind && data && property.isEdit) {
    if (data[name2] === undefined) data[name2] = value;
    else if (data[name2] !== value) value = data[name2];
  }

  return value;
};

const getValue = (property, value) => {
  if (value === undefined) return null;
  if (property.dataType === 'bool') return value.toString() === "true" || parseInt(value, 10) === 1;
  if (typeof value === "string") return Common.trim(value);
  if (Common.isArray(value) && property.isString) return value.join(",");
  if (Common.isArray(value) && property.isJson) {
    if (value.length === 0) return '';
    return JSON.stringify(value);
  }
  return value;
};

export default {
  getProps,
  load,
  getPropertyItem,
  renderProperties,
  getClassName,
  getLinkAction,
  getImageLink,
  getRightImageLink,
  initSetView,
  renderView,
  getClassNames,
  invokeEventAction,
  getEntity,
  renderProperties2,
  setStyle,
  setValueTextName,
  getInitValue,
  getValue
};